package youcheng.work.view_zhexian;

import static android.bluetooth.BluetoothDevice.DEVICE_TYPE_CLASSIC;
import static android.bluetooth.BluetoothDevice.DEVICE_TYPE_DUAL;
import static android.bluetooth.BluetoothDevice.DEVICE_TYPE_LE;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import java.util.ArrayList;
import java.util.Set;

public class BLEDeviceListActivity extends AppCompatActivity {
    // Debug
    private static final String TAG = "DeviceSearchActivity";

    private boolean D = false;

    // view
    private ListView mlvBTDevice;
    private Button mbtnReturn;

    private ImageView mbtnRefresh;
    private ProgressBar mprgBar;

    public static String EXTRAS_DEVICE = "Device";
    public static String EXTRAS_UART = "DeviceUART";//串口
    public static String EXTRAS_TXO = "DeviceTXO"; //发送数据
    public static String EXTRAS_RXI = "DeviceRXI"; //接受数据
    public static String EXTRAS_TYPE = "DeviceTYPE";//设备类型

    // 设备列表适配器
    private LeDeviceListAdapter mLeDeviceListAdapter;
    private BluetoothAdapter mBtAdapter;
    // 蓝牙适配器
    private BluetoothAdapter mBluetoothAdapter;
    // 意向请求代码
    private static final int REQUEST_ENABLE_BT = 1;
    private static final int REQUEST_CONNECT_DEVICE = 2;
    // Stops scanning after 5 seconds
    private static final long SCAN_PERIOD = 20000;
    // status of ble scan
    private boolean mScanning;

    private Handler mHandler;
    static Context mcontext;

    EditText uart, txd, rxi;
    static Context mContext;

    String bleUUID[] = {"0000FFE0-0000-1000-8000-00805F9B34FB",
            "0000FFE1-0000-1000-8000-00805F9B34FB",
            "0000FFE1-0000-1000-8000-00805F9B34FB"};


    Set<BluetoothDevice> pairedDevices;
    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bledevice_list);
        mHandler = new Handler();
        mcontext = this;
        mContext = this;
        //蓝牙初始化 此处适用于蓝牙连接未断开，重新获取蓝牙
        //final修饰成员变量：该成员变量必须在其所在类对象创建之前被初始化（且只能被初始化一次）。
        final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();//系统的蓝牙设备适配器
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();//设备列表的蓝牙设备适配器

        // judge whether android have bluetooth
        //判断android是否有蓝牙
        if (null == mBluetoothAdapter) {
            if (D) Log.e(TAG, "This device do not support Bluetooth");
            Dialog alertDialog = new AlertDialog.Builder(this).
                    setMessage("This device do not support Bluetooth").
                    create();
            alertDialog.show();
            BLEDeviceListActivity.this.finish();
        }

        uart = findViewById(R.id.serviceinput);//serviceuuid
        txd = findViewById(R.id.txinput);//writeuuid
        rxi = findViewById(R.id.rxinput);//notifyuuid
        uart.setText(Read_config("uart"));
        txd.setText(Read_config("txo"));
        rxi.setText(Read_config("rxi"));

        // Register for broadcasts when a device is discovered 注册发现设备时广播
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(mReceiver, filter);
        // Register for broadcasts when discovery has finished 注册发现完成后广播
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, filter);

        // ensure that Bluetooth exists
        if (!EnsureBleExist()) {
            if (D) Log.e(TAG, "This device do not support BLE");
            finish();
        }

        // device list initial 设备列表初始化
        mlvBTDevice = (ListView) findViewById(R.id.lvBTDevices);
        //给列表设置点击事件，点击即可连接
        mlvBTDevice.setOnItemClickListener(new ItemClickEvent());




        // refresh button initial
        mbtnRefresh = (ImageView) findViewById(R.id.refresh);
        mbtnRefresh.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if (D) Log.d(TAG, "refresh the data list");

                // clear the adapter
                mLeDeviceListAdapter.clear();

                // start the le scan
                if (false == mScanning) {
                    ScanLeDevice(true);
                }

            }
        });
        //mbtnRefresh.setVisibility(View.GONE);

        // process bar initial
        mprgBar = (ProgressBar) findViewById(R.id.progress_bar);
        mprgBar.setVisibility(View.GONE);

        bleUUID = Read_LastUUID();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            //申请定位权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    1);
        } else if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            //申请定位权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                    2);
        }
        // Get a set of currently paired devices 获取一组当前配对的设备
        pairedDevices = mBtAdapter.getBondedDevices();

        // If there are paired devices, add each one to the ArrayAdapter
        // 如果有配对的设备，请将每个设备添加到ArrayAdapter
        Log.d("paitDevice", "" + pairedDevices.size());
        if (pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                //mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                Log.d("paitDevice", device.getName() + "\n" + device.getAddress());
            }
        }


    }
    //onRequestPermissionsResult 请求权限结果
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1: // If request is cancelled, the result arrays are empty.
                if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) ;
                else Toast.makeText(this, "app没有定位权限将无法搜索蓝牙设备!", Toast.LENGTH_LONG);
                break;
            case 2:
                if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) ;
                else Toast.makeText(this, "app没有定位权限将无法搜索蓝牙设备!", Toast.LENGTH_LONG);
                break;
        }
    }

    // judge the support of ble in android
    // 判断ble在android中的支持
    private boolean EnsureBleExist() {
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, "This device does not support BLE", Toast.LENGTH_LONG).show();
            return false;
        }
        return true;
    }


    // 打开蓝牙请求
    @Override
    protected void onResume() {
        if (D) Log.d(TAG, "-------onResume-------");
        super.onResume();
        // Ensures Bluetooth is enabled on the device.  If Bluetooth is not currently enabled,
        // fire an intent to display a dialog asking the user to grant permission to enable it.
        if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.isEnabled()) {
                if (D) Log.d(TAG, "start bluetooth");
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }

        // Get a set of currently paired devices
        //获取一组当前已经配对的设备放进设备列表适配器里
        pairedDevices = mBluetoothAdapter.getBondedDevices();
        // Initializes list view adapter. 初始化设备列表
        mLeDeviceListAdapter = new LeDeviceListAdapter();
        // set the adapter 将视图里的列表设置为蓝牙设备列表
        mlvBTDevice.setAdapter(mLeDeviceListAdapter);

    }



    private class ItemClickEvent implements AdapterView.OnItemClickListener {

        @SuppressLint("SuspiciousIndentation")
        @Override
        public void onItemClick(AdapterView<?> l, View v, int position, long id) {
            // TODO Auto-generated method stub
            //根据列表被点击位置获取特定的蓝牙设备
            final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
            if (D)
            if (device == null) return;//判空操作
            String Type = mLeDeviceListAdapter.getDeviceType(position);
            // store the information for result
            //存储结果信息
            // 在Activity中，激活另一个Activity时可以在Intent对象中封装数据  Mainclass 连接消息收发界面
            Intent intent = new Intent(getApplicationContext(),BLEIOActivity.class);
            //Key-value 键值对 将点击获取的信息以键值对形式存储 封装好
            intent.putExtra(EXTRAS_DEVICE, device);
            intent.putExtra(EXTRAS_TYPE, Type);
            Log.d("Type", Type);

            //如果设备类型是BLE则继续封装
            if (Type.equals("[BLE]") || Type == "[BLE]") {

                intent.putExtra(EXTRAS_UART, bleUUID[0]);
                intent.putExtra(EXTRAS_RXI, bleUUID[1]);
                intent.putExtra(EXTRAS_TXO, bleUUID[2]);
            }
            //将封装好的数据传入并且连接设备
            startActivityForResult(intent, REQUEST_CONNECT_DEVICE);

        }
    }
    //暂停
    @Override
    protected void onPause() {
        if (D) Log.d(TAG, "-------onPause-------");

        // stop the le scan when close the activity
        if (true == mScanning) {
            ScanLeDevice(false);
        }
        // clear the adapter
        mLeDeviceListAdapter.clear();
        super.onPause();
    }

    //确保我们不再开启探索蓝牙设备
    @Override
    protected void onDestroy() {
        super.onDestroy();

        // Make sure we're not doing discovery anymore
        if (mBtAdapter != null) {

            mBtAdapter.cancelDiscovery();
        }

        // Unregister broadcast listeners
        //注销当前的广播监听器
        this.unregisterReceiver(mReceiver);
    }

    // The BroadcastReceiver that listens for discovered devices and
    // changes the title when discovery is finished
    //侦听发现的设备和发现完成后更改标题
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                //从Intent获取蓝牙设备对象
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
                String deviceName = device.getName();
                //设置列表项显示信息
                if ((device != null) && (deviceName != null && deviceName.length() > 0)) {
                    mLeDeviceListAdapter.addDevice(rssi, device);
                    mLeDeviceListAdapter.notifyDataSetChanged();
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                if (mLeDeviceListAdapter.getCount() == 0) {
                    //showTextToast("搜索不到设备，请确认是否开启了权限");
                    if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        //申请权限
                        ActivityCompat.requestPermissions((Activity) mContext, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                1);
                    } else if (ActivityCompat.checkSelfPermission((Activity) mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        //申请权限
                        ActivityCompat.requestPermissions((Activity) mContext, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                                2);
                    }
                }

            }
        }
    };

    String[] Read_LastUUID() {
        String[] uuid = new String[3];
        //调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他 组件共享.
        //E 为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
        SharedPreferences config = mcontext.getSharedPreferences("perference", MODE_PRIVATE);
        uuid[0] = config.getString("Lastuuid0", "0000FFE0-0000-1000-8000-00805F9B34FB");
        uuid[1] = config.getString("Lastuuid1", "0000FFE1-0000-1000-8000-00805F9B34FB");
        uuid[2] = config.getString("Lastuuid2", "0000FFE1-0000-1000-8000-00805F9B34FB");
        return uuid;
    }
    // Control le scan 控制le 扫描 根据 传参停止或者开始
    @SuppressLint("NewApi")
    private void ScanLeDevice(boolean enable) {
        //remove the stop le scan runnable
        mHandler.removeCallbacks(mStopLeScan);

        // control the process bar and le scan
        if (true == enable) {
            doDiscovery();
            // avoid repetition operator
            //避免重复开启扫描
            if (mScanning == enable) {
                if (D) Log.e(TAG, "the le scan is already on");
                return;
            }
            // Stops scanning after a pre-defined scan period.
            //在预定义的扫描周期后停止扫描。
            mHandler.postDelayed(mStopLeScan, SCAN_PERIOD);
            if (D) Log.d(TAG, "start the le scan, on time is " + SCAN_PERIOD + "ms");

            mBluetoothAdapter.startLeScan(mLeScanCallback);

            mprgBar.setVisibility(View.VISIBLE);//点击可见
            mbtnRefresh.setVisibility(View.GONE);//隐藏
        } else {
            //停止扫描
            // avoid repetition operator
            if (mScanning == enable) {
                if (D) Log.e(TAG, "the le scan is already off");
                return;
            }
            if (D) Log.d(TAG, "stop the le scan");

            mBluetoothAdapter.stopLeScan(mLeScanCallback);

            mprgBar.setVisibility(View.GONE);
            mbtnRefresh.setVisibility(View.VISIBLE);
        }
        // update le scan status
        mScanning = enable;
    }
    // Stops scanning after a pre-defined scan period.
    //在预定义的扫描周期后停止扫描。
    Runnable mStopLeScan = new Runnable() {
        @Override
        public void run() {
            if (D) Log.d(TAG, "le delay time reached");
            // Stop le scan, delay SCAN_PERIOD ms
            ScanLeDevice(false);
        }
    };
    //开启发现蓝牙设备
    private void doDiscovery() {
        if (D) Log.d(TAG, "doDiscovery()");
        // If we're already discovering, stop it

        if (mBtAdapter.isDiscovering()) {
            mBtAdapter.cancelDiscovery();
        }
        mBtAdapter.startDiscovery();
    }
    @SuppressLint("NewApi")
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    // add the device to the adaper

                    Log.d(TAG, "find a ble device, name is " + device.getName()
                            + ", addr is " + device.getAddress()
                            + "rssi is " + String.valueOf(rssi));

                    // set the list item show information
                    //设置列表项显示信息
                    final String deviceName = device.getName();
                    if ((device != null) && (deviceName != null && deviceName.length() > 0)) {
                        if (true) {
                            //mLeDeviceListAdapter.addDevice(rssi, device,true);
                            //mLeDeviceListAdapter.notifyDataSetChanged();
                        }
                    }
                }
            });
        }
    };


    //判断元素与已匹配设备列表里的元素是否一样
    //若一样则返回10 证明已经配对
    //若不一样则返回0 证明未配对
    public int getIsP(BluetoothDevice ndevice) {
        if (pairedDevices.size() > 0) {
            //遍历数组元素
            for (BluetoothDevice device : pairedDevices) {
                //mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                if (device.equals(ndevice)) {
                    Log.e("pairedDevice", device.getName() + "\n" + device.getAddress());
                    return 10;
                }
            }

            Log.e("paitDevice", ndevice.getName() + "un parired--=");
        }

        return 0;
    }


    static String Read_config(String name) {
        SharedPreferences config = mcontext.getSharedPreferences("perference", MODE_PRIVATE);
        return config.getString(name, "");
    }
//------------------------------------------------------------------------------------------------------------


    // Adapter for holding devices found through scanning.
    //通过扫描找到用于固定设备的适配器。
    private class LeDeviceListAdapter extends BaseAdapter {
        private ArrayList<BluetoothDevice> mLeDevices; //存放蓝牙设备的列表
        private ArrayList<Integer> mRssi;//存放整数的信号强度列表
        private ArrayList<String> Type;  //存放字符的设备类型列表
        private ArrayList<Integer> paired;//匹配
        //private HashMap<Integer, BluetoothDevice> mLeDevices;
        private LayoutInflater mInflator;

        public LeDeviceListAdapter() {
            super();
            mLeDevices = new ArrayList<BluetoothDevice>();
            mRssi = new ArrayList<Integer>();
            Type = new ArrayList<String>();
            paired = new ArrayList<Integer>();
            mInflator = BLEDeviceListActivity.this.getLayoutInflater();
        }

        //
        public void addDevice(int rssi, BluetoothDevice device) {
            String mType;
            boolean isduab = false;

            //判断获取的类型 绑定给mType
            switch (device.getType()) {
                case DEVICE_TYPE_CLASSIC:
                    mType = "[SPP]";
                    break;
                case DEVICE_TYPE_LE:
                    mType = "[BLE]";
                    break;
                case DEVICE_TYPE_DUAL:
                    mType = "[BLE]";
                    isduab = true;
                    break;
                default:
                    mType = "[UNKNOWN]";
                    break;
            }
            //操作蓝牙设备列表未发现的蓝牙设备
            if (!mLeDevices.contains(device)) {
                if (isduab == true) {
                    mLeDevices.add(device);
                    Type.add("[SPP]");
                    mRssi.add(rssi);
                    paired.add(getIsP(device));

                    mLeDevices.add(device);
                    Type.add("[BLE]");
                    mRssi.add(rssi);
                    paired.add(0);
                } else {
                    mLeDevices.add(device);
                    Type.add(mType);
                    mRssi.add(rssi);
                    if (mType.equals("[SPP]") || mType == "[SPP]") {
                        paired.add(getIsP(device));
                    } else {
                        paired.add(0);
                    }
                }


            } else {
                //int index = mLeDevices.indexOf(device);
                //mRssi.set(index,rssi);
                for (int i = 0; i < mLeDevices.size(); i++) {
                    if (mLeDevices.get(i).equals(device)) {
                        mRssi.set(i, rssi);//索引 要素
                    }
                }
                Log.d("RSSI", device.getName() + "  " + rssi);

            }
        }

        public BluetoothDevice getDevice(int position) {
            return mLeDevices.get(position);
        }

        public String getDeviceType(int position) {
            return Type.get(position);
        }

        public void clear() {
            mLeDevices.clear();
            paired.clear();
            mRssi.clear();
            Type.clear();
        }

        @Override
        public int getCount() {
            return mLeDevices.size();
        }

        @Override
        public Object getItem(int i) {
            return mLeDevices.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder viewHolder;
            // General ListView optimization code.
            if (view == null) {
                view = mInflator.inflate(R.layout.ble_listitem_device, null);
                viewHolder = new ViewHolder();
                viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
                viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
                viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
                viewHolder.backG = (View) view.findViewById(R.id.backg);

                view.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) view.getTag();
            }

            // get the device information
            BluetoothDevice device = mLeDevices.get(i);

            // set the list item show information
            //设置列表项显示信息
            final String deviceName = device.getName();

            if (deviceName != null && deviceName.length() > 0)
                viewHolder.deviceName.setText(Get_Name(device.getAddress(),deviceName));
            else
                viewHolder.deviceName.setText(Get_Name(device.getAddress(),"unknown device"));
            viewHolder.deviceAddress.setText(device.getAddress());
            viewHolder.deviceRssi.setText(Type.get(i)+"  RSSI:"+String.valueOf(mRssi.get(i)));

            int ispair = paired.get(i);
            if( ispair > 5){
                //viewHolder.backG.setBackgroundColor(0x5010ee10);
                Log.e("Getview","Set");
                viewHolder.deviceRssi.setTextColor(0xffff9501);
                viewHolder.deviceAddress.setTextColor(0xffff9501);
                viewHolder.deviceName.setTextColor(0xffff9501);
            }else {
                viewHolder.deviceRssi.setTextColor(0xffffffff);
                viewHolder.deviceAddress.setTextColor(0xffffffff);
                viewHolder.deviceName.setTextColor(0xffffffff);
                //viewHolder.backG.setBackgroundColor(0x0010ee10);
                Log.e("Getview","unSet");
            }
            Log.e("Getview","now index " + i + "   val = "+ ispair + "    " + deviceName);
            return view;
        }
    }

    static class ViewHolder {
        TextView deviceName;
        TextView deviceAddress;
        TextView deviceRssi;
        View backG;
    }

    static String Get_Name(String add,String dname){
			/*
			String name="";
			name = Read_config(add);
			if(name.length()<2){
				name = Save_config(add,dname);
			}
			return name;*/
        return dname;
    }




}